/*
Copyright (c) 2022 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import QuickTimeDictionary from './QuickTimeDictionary'
import QuickTimeDirectory from './QuickTimeDirectory'
import Rational from '../../lang/Rational'
import TagDescriptor from '../TagDescriptor'
import LogUtil from '../../tools/LogUtils'

const TAG: string = "QuickTimeDescriptor";

export default class  QuickTimeDescriptor extends TagDescriptor<QuickTimeDirectory> {
  public constructor(directory: QuickTimeDirectory) {
    super(directory);
  }

  public getDescription(tagType: number): string {
    LogUtil.debug(TAG, `getDescription start, tagType: ${tagType}`);
    switch (tagType) {
      case QuickTimeDirectory.TAG_MAJOR_BRAND:
        return this.getMajorBrandDescription();
      case QuickTimeDirectory.TAG_COMPATIBLE_BRANDS:
        return this.getCompatibleBrandsDescription();
      case QuickTimeDirectory.TAG_DURATION_SECONDS:
        return this.getDurationDescription();
      default:
        return super.getDescription(tagType);
    }
  }

  private getMajorBrandDescription(): string {
    LogUtil.debug(TAG, `getMajorBrandDescription start`);
    let value: Int8Array = this._directory.getByteArray(QuickTimeDirectory.TAG_MAJOR_BRAND);
    if (value == null) {
      LogUtil.error(TAG, `getMajorBrandDescription end, value is null`);
      return null;
    }
    LogUtil.debug(TAG, `getMajorBrandDescription end, value: ${value}`);
    return QuickTimeDictionary.lookup(QuickTimeDirectory.TAG_MAJOR_BRAND, value.toString());
  }

  private getCompatibleBrandsDescription(): string {
    LogUtil.debug(TAG, `getCompatibleBrandsDescription start`);
    let values: Array<string> = this._directory.getStringArray(QuickTimeDirectory.TAG_COMPATIBLE_BRANDS);
    if (values == null) {
      LogUtil.error(TAG, `getCompatibleBrandsDescription end, values is null`);
      return null;
    }

    let compatibleBrandsValues: Set<string> = new Set<string>();
    for (let value in values) {
      let compatibleBrandsValue: string = QuickTimeDictionary.lookup(QuickTimeDirectory.TAG_MAJOR_BRAND, value);
      compatibleBrandsValues.add(compatibleBrandsValue == null ? value : compatibleBrandsValue);
    }
    LogUtil.debug(TAG, `getCompatibleBrandsDescription end`);
    return Array.from(compatibleBrandsValues).toString();
  }

  private getDurationDescription(): string {
    LogUtil.debug(TAG, `getDurationDescription start`);
    let duration: Rational = this._directory.getRational(QuickTimeDirectory.TAG_DURATION_SECONDS);
    if (duration == null) {
      LogUtil.error(TAG, `getDurationDescription end, duration is null`);
      return null;
    }

    let value: number = duration.numberValue();
    let hours: number = parseInt(String(value / (Math.pow(60, 2))).split('.')[0]);
    let hoursStr: string = String(value / (Math.pow(60, 2))).split('.')[0];
    if (hoursStr != null && hoursStr.length == 1) {
      hoursStr = '0' + hoursStr;
    }

    let minutes: number = parseInt(String(value / (Math.pow(60, 1)) - (hours * 60)).split('.')[0]);
    let minutesStr: string = String(value / (Math.pow(60, 1)) - (hours * 60)).split('.')[0];
    if (minutesStr != null && minutesStr.length == 1) {
      minutesStr = '0' + minutesStr;
    }
    let seconds: number = Math.ceil(value / (Math.pow(60, 0)) - (minutes * 60));
    let secondsStr: string = String(Math.ceil(value / (Math.pow(60, 0)) - (minutes * 60))).split('.')[0];
    if (secondsStr != null && secondsStr.length == 1) {
      secondsStr = '0' + secondsStr;
    }
    let time: string = hoursStr + ':' + minutesStr + ":" + secondsStr;
    LogUtil.debug(TAG, `getDurationDescription end, time: ${time}`);
    return time;
  }
}
